package timbap.visualizer.api.model;

import processing.core.PApplet;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.zip.Adler32;
import java.util.zip.Checksum;

/**
 * The <code>ArtworkData</code> class represents the image data
 * of an artwork file.
 *
 * @author  Andreas Pabst
 * @see     PlaylistEntry
 */
public class ArtworkData {

	private byte[] rawData;
	private Format format;
	
	public enum Format {
		JPEG,
		PNG,
		GIF,
		UNSUPPORTED
	}
	
	public ArtworkData(byte[] pRawData, Format pFormat) {
		super();
		this.rawData = pRawData;
		this.format = pFormat;
	}
	
	public ArtworkData(byte[] pRawData, String pMimeType) {
		this(pRawData, getFormatFromMimeType(pMimeType));
	}
	
	public ArtworkData(File pFile) throws FileNotFoundException, IOException {
		this(getRawDataFromFile(pFile), getFormatFromFileExtension(pFile));
	}
	
	private static byte[] getRawDataFromFile(File pFile) throws FileNotFoundException, IOException {
		return PApplet.loadBytes(new FileInputStream(pFile));
	}

	private static Format getFormatFromMimeType(String pMimeType) {
		String tLowerCaseMimeType = pMimeType.toLowerCase();
		if (tLowerCaseMimeType.endsWith("/jpg") || tLowerCaseMimeType.endsWith("/jpeg")) {
			return Format.JPEG;
		} else if (tLowerCaseMimeType.endsWith("/gif")) {
			return Format.GIF;
		} else if (tLowerCaseMimeType.endsWith("/png")) {
			return Format.PNG;
		} else {
			return Format.UNSUPPORTED;
		}
	}
	
	private static Format getFormatFromFileExtension(File pFile) {
		String tFileName = pFile.getName().toLowerCase();
		if (tFileName.endsWith("jpg") || tFileName.endsWith("jpeg")) {
			return Format.JPEG;
		} else if (tFileName.endsWith("gif")) {
			return Format.GIF;
		} else if (tFileName.endsWith("png")) {
			return Format.PNG;
		} else {
			return Format.UNSUPPORTED;
		}
	}

	public byte[] getRawData() {
		return rawData;
	}

	public void setRawData(byte[] rawData) {
		this.rawData = rawData;
	}

	public Format getFormat() {
		return format;
	}

	public void setFormat(Format format) {
		this.format = format;
	}
	
	public Image toImage() throws IOException {
        return Toolkit.getDefaultToolkit().createImage(rawData);
	}

    public Long getChecksum() {
        Checksum tChecksum = new Adler32();
        tChecksum.update(rawData, 0, rawData.length);
        return tChecksum.getValue();
    }

}
